import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:two_dimensional_scrollables/two_dimensional_scrollables.dart';

class SimpleTreePage extends StatefulWidget {
  const SimpleTreePage({Key? key}) : super(key: key);

  @override
  State<SimpleTreePage> createState() => _SimpleTreePageState();
}

class _SimpleTreePageState extends State<SimpleTreePage> {
  final TreeViewController treeController = TreeViewController();
  final ScrollController _horizontalController = ScrollController();
  TreeViewNode<String>? _selectedNode;
  final ScrollController _verticalController = ScrollController();

  @override
  void dispose() {
    super.dispose();
    _verticalController.dispose();
    _horizontalController.dispose();
  }

  final List<TreeViewNode<String>> _tree = <TreeViewNode<String>>[
    TreeViewNode<String>("It's supercalifragilisticexpialidocious",
        children: <TreeViewNode<String>>[
          TreeViewNode<String>(
            'Even though the sound of it is something quite atrocious',
          ),
          TreeViewNode<String>(
            "If you say it loud enough you'll always sound precocious",
          )
        ]),
    TreeViewNode<String>(
      'Supercalifragilisticexpialidocious',
      children: <TreeViewNode<String>>[
        TreeViewNode<String>(
          'Um-dittle-ittl-um-dittle-I',
          children: <TreeViewNode<String>>[
            TreeViewNode<String>(
              'Um-dittle-ittl-um-dittle-I',
              children: <TreeViewNode<String>>[
                TreeViewNode<String>(
                  'Um-dittle-ittl-um-dittle-I',
                  children: <TreeViewNode<String>>[
                    TreeViewNode<String>('Um-dittle-ittl-um-dittle-I',
                        children: <TreeViewNode<String>>[
                          TreeViewNode<String>('Um-dittle-ittl-um-dittle-I'),
                        ])
                  ],
                ),
              ],
            ),
          ],
        ),
      ],
    ),
  ];

  Map<Type, GestureRecognizerFactory> _getTapRecognizer(
      TreeViewNode<String> node) {
    return <Type, GestureRecognizerFactory>{
      TapGestureRecognizer:
          GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
              () => TapGestureRecognizer(),
              (TapGestureRecognizer t) => t.onTap = () {
                    setState(() {
                      _selectedNode = node;
                    });
                  }),
    };
  }

  Widget _getTree() {
    return DecoratedBox(
        decoration: BoxDecoration(border: Border.all()),
        child: Scrollbar(
          controller: _verticalController,
          thumbVisibility: true,
          child: TreeView<String>(
            controller: treeController,
            verticalDetails:
                ScrollableDetails.vertical(controller: _verticalController),
            horizontalDetails:
                ScrollableDetails.horizontal(controller: _horizontalController),
            tree: _tree,
            onNodeToggle: (TreeViewNode<String> node) {
              setState(() {
                _selectedNode = node;
              });
            },
            treeRowBuilder: (TreeViewNode<String> node) {
              if (_selectedNode == node) {
                return TreeView.defaultTreeRowBuilder(node).copyWith(
                    recognizerFactories: _getTapRecognizer(node),
                    backgroundDecoration: TreeRowDecoration(
                      color: Colors.purple[100],
                    ));
              }
              return TreeView.defaultTreeRowBuilder(node).copyWith(
                recognizerFactories: _getTapRecognizer(node),
              );
            },
            indentation: TreeViewIndentationType.custom(50),
          ),
        ));
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final Size screenSize = MediaQuery.sizeOf(context);
    return Scaffold(
        appBar: AppBar(
          title: Text('simple_tree'),
        ),
        body: ScrollConfiguration(
          behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
          child: Padding(
            padding: EdgeInsets.symmetric(
                horizontal: screenSize.width * 0.25, vertical: 25),
            child: _getTree(),
          ),
        ));
  }
}
